package controller;

import java.util.List;

import model.EventType;
import model.Subject;
import modelInterfaces.IEventType;
import modelInterfaces.IPrediction;
import modelInterfaces.ISubject;
import pluginInterfaces.IRecommender;
import view.ViewRecommendersPanel;
import viewInterfaces.AbstractViewFactory;
import viewInterfaces.IViewRunSetup;
import controllerInterfaces.IControllerMain;
import controllerInterfaces.IControllerRunSetup;
import dao.DAOException;
import dao.DAOFactory;
import enums.DBMS;

/**
 * Controls the parameters to perform recommendations and so controls the execution of a recommendation algorithm setup   
 */
public class ControllerRunSetup implements IControllerRunSetup {

	/** MVC++ Main Controller 
	 * @see ControllerMain*/
	private IControllerMain mainController;
	
	/** View of Panel of recommenders
	 * @see ViewRecommendersPanel*/
	private IViewRunSetup view;
	
	/** Recommendation algorithm to execute*/	
	private IRecommender recommender;
	
	/** Target subject to perform recommendations*/ 
	private ISubject currentUser;
	
	/** Number of objects to recommend*/
	private int itemsAmountToRecommend;

	/** List of event types to consider in recommendation*/
	private List<IEventType> eventTypes;

	
	/**
	 * Class Constructor */	
	public ControllerRunSetup() {
		this.view = AbstractViewFactory.getAbstractViewFactory().getViewRun();
		this.view.setController(this);
		this.view.render();
		load();
	}
	
	/**
	 * Get subjects and charge the view with them 
	 */
	private void load() {
		try
		{
			this.view.setUserList(DAOFactory.getDAOFactory().getUserDAO().retrieveAll());
			this.view.setEventTypeList(DAOFactory.getDAOFactory().getEventTypeDAO().retrieveAll());
		}
		catch (DAOException e)
		{
			this.view.renderError(e.getCode(), e.getMessage());
			e.printStackTrace();
		}
		
	}

	/**
	 * Closes the view and finalizes this controller
	 */
	public void close() {
		this.view.close();
		this.mainController.stopRun();
	}


	/**
	 * Set the MVC++ Main Class for this controller.</br>
	 * ControllerMain is manipulable through {@link IControllerMain} interface
	 * @param	controllerMain	MVC++ Main Controller
	 * @see	ControllerMain
	 * @see IControllerMain
	 */
	public void SetMainController(IControllerMain controllerMain) {
		this.mainController = controllerMain;
	}

	
	/**
	 * Sets the recommendation algorithm setup ({@link Recommender}}) to run.</br>
	 * {@link Recommender} is manipulable though {@link IRecommender} interface.
	 * @param	recommender	the recommendation algorithm setup
	 * @see Recommender
	 * @see IRecommender
	 */
	public void SetRecommender(IRecommender recommender) {
		this.recommender = recommender;
	}
	
	
	/**
	 * Sets the {@link Subject} to provide him recommendations</br>
	 * {@link Subject} is manipulable though {@link ISubject} interface.
	 * @param	currentUser	target subject
	 * @see Subject
	 * @see ISubject
	 */	
	public void SetCurrentUser(ISubject currentUser)
	{
		this.currentUser = currentUser;
	}

	
	/**
	 * Sets the Number of objects to recommend.
	 * @param	itemsAmountToRecommend	number of objects to recommend.
	 */	
	public void SetItemAmountToRecommend(int itemsAmountToRecommend)
	{
		this.itemsAmountToRecommend = itemsAmountToRecommend;
	}


	
	/**
	 * Sets the {@link EventType} list to provide him recommendations</br>
	 * {@link EventType} is manipulable though {@link IEventType} interface.
	 * @param	eventTypes	list of event types to consider in recommendation
	 * @see EventType
	 * @see IEventType
	 */		
	public void SetEventTypes(List<IEventType> eventTypes) {
		this.eventTypes = eventTypes;
	}	
	
	
	/**
	 * Execute the {@link Recommender}
	 */
	public void run() {
				
		List<IPrediction> predictionList = null;
		try
		{
			predictionList = this.recommender.getAlgorithm().recommend(
					this.currentUser, 
					DAOFactory.getDAOFactory().getEventDAO().retrieveAllFromTypes(this.eventTypes),
					this.itemsAmountToRecommend
					);
		}
		catch (DAOException e)
		{
			this.view.renderError(e.getCode(), e.getMessage());
			e.printStackTrace();
		} 
		
		this.view.setPredictions(predictionList);
	}


}

